package com.nifostasky.main.terminal;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 使用Process 方式执行命令
 * 首先了解一下Process类，顾名思义，这个类叫进程类，封装了一个进程（即一个执行程序）。
 *
 * > 官方解释：
 * > Process类提供了执行进程输入、执行输出到进程、等待进程完成、检查进程退出状态以及销毁（杀死）进程的方法。
 *
 * 提供了6个抽象方法
 *
 * - `public abstract OutputStream getOutputStream(); `返回连接到子进程正常输入的输出流
 * - `public abstract InputStream getInputStream(); `返回连接到子进程正常输出的输入流
 * - `public abstract InputStream getErrorStream(); `返回连接到子进程错误输出的输入流
 * - `public abstract int waitFor() throws InterruptedException; `使当前线程在必要时等待，直到此Process对象表示的Process终止
 * - `public abstract int exitValue(); `此Process对象表示的子流程的退出值。 按照惯例，值0表示正常终止。抛出IllegalThreadStateException的话表示此Process对象表示的子Process尚未终止
 * - `public abstract void destroy(); `杀死子进程。 此Process对象表示的子流程是否被强制终止取决于实现
 */
public class ProcessCase {

    public static Boolean processTest(){
        String command = "ping www.baidu.com";
        /* 命令用List存储 */
        String[] commandSplit = command.split(" ");
        List<String> lcommand = new ArrayList<>(Arrays.asList(commandSplit));

        ProcessBuilder processBuilder = new ProcessBuilder(lcommand);

        // 此对象的start()方法随后启动的子进程生成的任何错误输出都将与标准输出合并，以便可以使用Process.getInputStream()方法读取两者
        processBuilder.redirectErrorStream(true);
        try{
            Process process = processBuilder.start();
            InputStream is = process.getInputStream();
            BufferedReader bs = new BufferedReader(new InputStreamReader(is));


            /**
             * BufferedReader的readLine()方法是阻塞式的,
             * 如果到达流末尾, 就返回null,
             * 但如果client的socket末经关闭就销毁, 则会产生IO异常.
             * 正常的方法就是使用socket.close()关闭不需要的socket.
             */
            String line = null;
            while ((line = bs.readLine()) != null) {
                System.out.println(line);
            }


            process.waitFor(); // 等待process子进程终止

            //关闭流
            bs.close();
            is.close();

            return process.exitValue() == 0;
        }catch (Exception e){
            return false;
        }
    }

    public static void main(String[] args) {
        System.out.println("\n"+"=======================================================================================================================");
        ProcessCase.processTest();
        System.out.println("======================================================================================================================="+"\n");

    }
}
